﻿using System;
using System.Collections.Generic;
using System.Text;
using Commons.TypeUtil.ConverterTypes;
using System.Reflection;
using Commons.TypeUtil.ConverterTypes;

namespace Commons.TypeUtil
{
    /// <summary>
    /// 字符和值相互转换
    /// </summary>
    public class StringValueConverter
    {
        private Dictionary<object, IConvertibility> _converterMapping = new Dictionary<object,IConvertibility>();

        public Dictionary<object, IConvertibility> ConverterMapping
        {
            get { return _converterMapping; }
        }
        /// <summary>
        /// 加载这个程序集下的转换器
        /// </summary>
        public StringValueConverter()
        {
            Type it = typeof(IConvertibility);
            Assembly assembly = Assembly.GetAssembly(it);
            Type[] ts = assembly.GetExportedTypes();
            
            foreach (Type t in ts)
            {
                if (t.GetInterface("IConvertibility") != null)
                {
                    IConvertibility converter = (IConvertibility)Activator.CreateInstance(t);
                    RegisterConverter(converter);
                }
            }
        }

        /// <summary>
        /// 有没有转换的类
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool HasConverter(object t)
        {
            return ConverterMapping.ContainsKey(t);
        }

        /// <summary>
        /// 注册一个转换类
        /// </summary>
        /// <param name="converter"></param>
        public void RegisterConverter(IConvertibility converter)
        {
            object[] keys = converter.GetRegisterKeys();
            if(keys != null && keys.Length > 0)
            {
                foreach(object o in keys)
                {
                    if (ConverterMapping.ContainsKey(o))
                    {
                        ConverterMapping.Remove(o);
                    }
                    ConverterMapping.Add(o, converter);
                }
            }
        }

        public object GetValue(object targetType, string strValue)
        {
            if (ConverterMapping.ContainsKey(targetType))
            {
                return ConverterMapping[targetType].GetValue(strValue);
            }
            throw new MissingConverterExceptions("没有发现注册过的类型转换器。" + targetType);
        }

        public string GetString(object targetType, object value)
        {
            if (ConverterMapping.ContainsKey(targetType))
            {
                return ConverterMapping[targetType].GetValueStr(value);
            }
            throw new MissingConverterExceptions("没有发现注册过的类型转换器。" + targetType);
        }

        /// <summary>
        /// 使用自身的类型来寻找对应得转换器
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public string GetString(object value)
        {
            return GetString(value.GetType(), value);
        }
    }

    public class MissingConverterExceptions : Exception
    {
        public MissingConverterExceptions(string message)
            :base(message)
        {
           
        }
    }
}
